package com.rzico.sbl.ui.statistic

import android.text.Editable
import android.text.InputFilter
import android.text.TextWatcher
import android.widget.EditText
import androidx.core.widget.doAfterTextChanged
import com.google.gson.Gson
import com.jeremyliao.liveeventbus.LiveEventBus
import com.lzg.extend.jackson.JsonUtil
import com.lzy.okgo.model.HttpMethod
import com.rzico.sbl.R
import com.rzico.sbl.databinding.ActivityStockStoreEditBinding
import com.rzico.sbl.model.BaseUrl
import com.rzico.sbl.model.GoodsData
import com.rzico.sbl.model.StockShop
import com.rzico.sbl.model.StockSupply
import com.rzico.sbl.model.StoreGoods
import com.rzico.sbl.ui.goods.GoodsActivity
import com.rzico.sbl.viewmodel.StatisticStockViewModel
import com.xinnuo.common.decoration.DividerLRDecoration
import com.xinnuo.common.extend.*
import com.xinnuo.common.helper.doubleValue
import com.xinnuo.common.helper.intValue
import com.xinnuo.common.listener._TextWatcher
import com.xinnuo.common.other.DecimalNumberFilter
import com.xinnuo.common.view.FullyLinearLayoutManager
import com.xinnuo.common_ui.base.BaseActivity
import com.xinnuo.common_ui.base.addItems
import com.xinnuo.common_ui.utils.showHintDialog
import com.xinnuo.common_ui.utils.showListDialog
import com.xinnuo.slimadapter.SlimAdapter
import org.json.JSONArray
import org.json.JSONObject

class StockStoreEditActivity : BaseActivity(R.layout.activity_stock_store_edit) {

    private val mBinding by lazy { ActivityStockStoreEditBinding.bind(getRootView()) }

    override fun getViewModel() = get<StatisticStockViewModel>()

    private val mGoodsList = arrayListOf<StoreGoods>()
    private val mShopList = arrayListOf<StockShop>()
    private val mSupplyList = arrayListOf<StockSupply>()
    private lateinit var mEditMode: String
    private var mStoreId = ""
    private var mShopId = ""
    private var mSupplyId = ""

    override fun initData() {
        initTitle(title = "入库编辑")

        initLayout()

        getShopList()
        getSupplyList()

        mStoreId
            .notEmpty {
                getData()
            }
    }

    private fun initLayout() {
        mBinding
            .storeList
            .apply {
                isNestedScrollingEnabled = false
                layoutManager = FullyLinearLayoutManager(getIContext())

                addItemDecoration(
                    DividerLRDecoration(
                        spaceL = 0f,
                        spaceR = 0f,
                        bottom = 0f
                    )
                )

                mAdapter = SlimAdapter.creator()
                    .register<StoreGoods>(R.layout.item_stock_store_edit) { jector, bean, index ->
                        jector.apply {
                            text(R.id.item_store_type, bean.name)

                            // 进货价
                            with<EditText>(R.id.item_store_price) {
                                if (it.tag != null && it.tag is TextWatcher) {
                                    it.removeTextChangedListener(it.tag as TextWatcher)
                                }

                                it.filters =
                                    arrayOf(DecimalNumberFilter(), InputFilter.LengthFilter(8))
                                bean.price.notEmpty {
                                    it.setText(bean.price.formatDecimal())
                                    it.setSelection(it.text.length)
                                }

                                val textWatcher = object : _TextWatcher() {
                                    override fun afterTextChanged(s: Editable) {
                                        bean.price = s.toString()

                                        totalAmount()
                                    }
                                }
                                it.addTextChangedListener(textWatcher)
                                it.tag = textWatcher
                            }

                            // 商品数量
                            with<EditText>(R.id.item_store_count) {
                                if (it.tag != null && it.tag is TextWatcher) {
                                    it.removeTextChangedListener(it.tag as TextWatcher)
                                }

                                bean.quantity.notEmpty {
                                    it.setText(bean.quantity)
                                    it.setSelection(it.text.length)
                                }

                                val textWatcher = object : _TextWatcher() {
                                    override fun afterTextChanged(s: Editable) {
                                        bean.quantity = s.toString()

                                        totalAmount()
                                    }
                                }
                                it.addTextChangedListener(textWatcher)
                                it.tag = textWatcher
                            }

                            clicked(R.id.item_store_del) {
                                mGoodsList.removeAt(index)

                                mAdapter.apply {
                                    notifyItemRemoved(index)
                                    notifyItemRangeChanged(index, itemCount - index)
                                }

                                totalAmount()
                            }
                        }
                    }
                    .attachTo(this)
            }

        mAdapter.setDataList(mGoodsList)
    }

    override fun initListener() {
        mEditMode = intent.getExtra("mode")
        mStoreId = intent.getExtra("storeId")

        mBinding.apply {
            arrayOf(
                DecimalNumberFilter(),
                InputFilter.LengthFilter(10)
            ).also {
                storeFee.filters = it
                storeAppend.filters = it
                storeCash.filters = it
                storeWechat.filters = it
                storeAlipay.filters = it
            }

            storeFee.doAfterTextChanged { totalDebt() }
            storeAppend.doAfterTextChanged { totalDebt() }
            storePay.doAfterTextChanged { totalDebt() }
            storeOld.doAfterTextChanged { totalDebt() }
            storeCash.doAfterTextChanged { totalDebt() }
            storeWechat.doAfterTextChanged { totalDebt() }
            storeAlipay.doAfterTextChanged { totalDebt() }

            storeAdd.oneClick {
                startActivityEx<GoodsActivity>("mode" to "single")
            }

            storeSupplyLl.oneClick {
                showSupplyDialog()
            }

            storeShopLl.oneClick {
                showShopDialog()
            }

            storeSure.oneClick {
                submitData(2)
            }

            storeSave.oneClick {
                submitData(1)
            }
        }

        LiveEventBus
            .get("manualGoods", GoodsData::class.java)
            .observe(this) {
                mGoodsList.add(
                    StoreGoods(
                        id = it.productId,
                        name = it.name
                    )
                )

                mAdapter.notifyDataSetChanged()
            }
    }

    private fun submitData(flag: Int) {
        when {
            mGoodsList.isEmpty() -> {
                showToast("请添加入库商品")
                return
            }

            mGoodsList.any { it.price.doubleValue == 0.0 }
                    || mGoodsList.any { it.quantity.intValue == 0 } -> {
                showToast("请完善商品信息")
                return
            }

            mSupplyId.isEmpty() -> {
                showToast("供应商信息获取失败，请返回重试")
                return
            }

            mShopId.isEmpty() -> {
                showToast("仓库信息获取失败，请返回重试")
                return
            }
        }

        showHintDialog(
            title = "保存入库",
            hint = conditionIf(
                flag == 1,
                "确定要保存采购信息吗？",
                "确定要保存采购信息并入库吗？"
            ),
            onSure = {
                mBinding.apply {
                    getViewModel()
                        .request(
                            requestUrl =
                            conditionIf(
                                mEditMode == "add",
                                BaseUrl.psiStoreAdd,
                                BaseUrl.psiStoreUpt
                            ),
                            isMultipart = true,
                            params = arrayOf(
                                "id" to mStoreId,
                                "flag" to flag,
                                "supplierId" to mSupplyId,
                                "shopId" to mShopId,
                                "freight" to storeFee.content,
                                "payAmount" to storeAppend.content,
                                "amount" to storePay.content,
                                "cashPay" to storeCash.content,
                                "weixinPay" to storeWechat.content,
                                "aliPay" to storeAlipay.content,
                                "repayment" to storeBack.content,
                                "arrears" to storeNew.content,
                                "memo" to storeMemo.textTrim,
                                "body" to Gson().toJson(mGoodsList)
                            ),
                            onSuccess = {
                                showToast("采购保存成功！")

                                // 刷新采购入库列表
                                LiveEventBus
                                    .get("storeList")
                                    .post("refresh")

                                finishView()
                            }
                        )
                }
            }
        )
    }

    private fun showSupplyDialog() {
        showListDialog(
            title = "请选择供应商",
            items = mSupplyList.map { it.name },
            listener = { index, hint ->
                val item = mSupplyList[index]

                mSupplyId = item.id
                mBinding.apply {
                    storeSupply.text = hint
                    storeOld.text = item.arrears.formatDecimal()
                }
            }
        )
    }

    private fun showShopDialog() {
        showListDialog(
            title = "请选择仓库",
            items = mShopList.map { it.shopName },
            listener = { index, hint ->
                mShopId = mShopList[index].id
                mBinding.storeShop.text = hint
            }
        )
    }

    /**
     * 获取店铺列表，含自提点
     */
    private fun getShopList() {
        getViewModel()
            .shopList(
                onSuccess = { list ->
                    mShopList.clear()
                    mShopList.addItems(list)

                    (mStoreId.isEmpty()
                            && mShopList.isNotEmpty())
                        .condition {
                            val item = mShopList.first()

                            mShopId = item.id
                            mBinding.storeShop.text = item.shopName
                        }
                }
            )
    }

    /**
     * 获取供应商列表
     */
    private fun getSupplyList() {
        getViewModel()
            .supplyList(
                page = 0,
                pageSize = 100,
                isLoading = true,
                onSuccess = { body ->
                    mSupplyList.clear()
                    mSupplyList.addItems(body.data)

                    (mStoreId.isEmpty()
                            && mSupplyList.isNotEmpty())
                        .condition {
                            val item = mSupplyList.first()

                            mSupplyId = item.id
                            mBinding.apply {
                                storeSupply.text = item.name
                                storeOld.text = item.arrears.formatDecimal()
                            }
                        }
                }
            )
    }

    override fun getData(index: Int, isLoading: Boolean) {
        getViewModel()
            .request(
                requestUrl = BaseUrl.psiStoreDet,
                requestMethod = HttpMethod.GET,
                params = arrayOf("id" to mStoreId),
                onSuccess = { result ->
                    val obj = JSONObject(result)

                    mSupplyId = obj.optNotNull("supplier")
                    mShopId = obj.optNotNull("shop")

                    mBinding.apply {
                        storeSupply.text = obj.optNotNull("supplierName")
                        storeShop.text = obj.optNotNull("shopName")
                        storeMemo.setText(obj.optNotNull("memo"))

                        storePay.text = obj.optNotNull("amountPaid").formatDecimal()
                        storeBack.text = obj.optNotNull("repayment").formatDecimal()
                        storeNew.text = obj.optNotNull("arrears").formatDecimal()

                        // 运费
                        obj.optNotNull("freight")
                            .also {
                                (it.doubleValue > 0)
                                    .condition {
                                        storeFee.setText(it.formatDecimal())
                                    }
                            }

                        // 附加费
                        obj.optNotNull("payAmount")
                            .also {
                                (it.doubleValue > 0)
                                    .condition {
                                        storeAppend.setText(it.formatDecimal())
                                    }
                            }

                        // 现金
                        obj.optNotNull("cashPay")
                            .also {
                                (it.doubleValue > 0)
                                    .condition {
                                        storeCash.setText(it.formatDecimal())
                                    }
                            }

                        // 微信
                        obj.optNotNull("weixinPay")
                            .also {
                                (it.doubleValue > 0)
                                    .condition {
                                        storeWechat.setText(it.formatDecimal())
                                    }
                            }

                        // 支付宝
                        obj.optNotNull("aliPay")
                            .also {
                                (it.doubleValue > 0)
                                    .condition {
                                        storeAlipay.setText(it.formatDecimal())
                                    }
                            }

                        /*---------------------- 商品信息 ----------------------*/
                        val objOrder = obj.optJSONArray("creditItems") ?: JSONArray()
                        mGoodsList.clear()
                        mGoodsList.addItems(
                            JsonUtil.toList(
                                objOrder.toString(),
                                StoreGoods::class.java
                            )
                        )
                        mAdapter.notifyDataSetChanged()
                    }
                }
            )
    }

    /**
     * 合计金额计算
     */
    private fun totalAmount() = kotlin.run {
        val realList = mGoodsList.filter { it.quantity.intValue > 0 }

        mBinding.storePay.text =
            realList.sumOf {
                it.price.doubleValue * it.quantity.intValue
            }.formatDecimal()
    }

    /**
     * 累计欠款计算
     */
    private fun totalDebt() {
        mBinding
            .apply {
                val amountThis =
                    (storeFee.textDouble
                            + storeAppend.textDouble
                            + storePay.textDouble)
                val amountOld = storeOld.textDouble
                val amountOut =
                    (storeCash.textDouble
                            + storeWechat.textDouble
                            + storeAlipay.textDouble)

                storeNew.text = (amountThis + amountOld - amountOut).formatDecimal()

                if (amountOld > 0 && amountOut > amountThis) {
                    val amountBack = amountOut - amountThis
                    storeBack.text =
                        (conditionIf(
                            amountBack < amountOld,
                            amountBack,
                            amountOld
                        )).formatDecimal()
                } else storeBack.text = "0.00"
            }
    }

}